package Model;

import Controller.LogManager;
import Controller.TransactionManager;
import java.io.IOException;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "Transaction", urlPatterns = {"/Transaction"})
public class Transaction extends HttpServlet{
    private static String creditNum = null,
            creditVerify = null,
            creditMonth = null,
            creditYear = null,
            password = null;
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        
        int result = TransactionManager.purchaseProduct(password, request.getSession());
        
        switch (result){
            case 1:
                response.sendRedirect("transaction.jsp?status=1");
                break;
            case 0:
                response.sendRedirect("transaction.jsp?status=0");
                break;
            case -1:
                response.sendRedirect("transaction.jsp?status=-1");
                break;
        }
        
        /*if ( TransactionManager.purchaseProduct(password) ) {
            LogManager.logEvent("Transaction." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.INFO, "Transaction Successful", request.getRemoteAddr(), String.valueOf(request.getSession().getAttribute("name")));
            response.sendRedirect("transaction.jsp?status=1");
        } else {
            LogManager.logEvent("Transaction." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.WARNING, "Transaction Unsuccessful", request.getRemoteAddr(), String.valueOf(request.getSession().getAttribute("name")));
            response.sendRedirect("transaction.jsp?status=0");
        }*/
    }
    
    private static boolean checkInput(HttpServletRequest request){
        creditNum = request.getParameter("credit-num");
        creditVerify = request.getParameter("credit-verification");
        creditMonth = request.getParameter("expiration-month");
        creditYear = request.getParameter("expiration-year");
        password = request.getParameter("buy-pw");
        
        //validates user inputs through regex
        String regexAlphaNum = "^[A-Za-z0-9]+$";
        String regexNum = "^[0-9]+$"; //whitelist
        Pattern pNum = Pattern.compile(regexNum, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE),
                pAlphaNum = Pattern.compile(regexAlphaNum, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
        Matcher mCreditVerify = pNum.matcher(creditVerify),
                mCreditNum = pNum.matcher(creditNum),
                mCreditYear = pNum.matcher(creditYear),
                mCreditMonth = pNum.matcher(creditMonth),
                mPassword = pAlphaNum.matcher(password);
        boolean resultCreditVerify = mCreditVerify.find(),
                resultCreditNum = mCreditNum.find(),
                resultCreditYear = mCreditYear.find(),
                resultCreditMonth = mCreditMonth.find(),
                resultPassword = mPassword.find();
        
        //checks if the forms have valid infromation 
        //and the forms have a value
        if( creditMonth.length() > 0 && 
                creditYear.length() > 0 && 
                (creditNum.length() > 0 && creditNum.length() <= 16) &&
                (creditVerify.length() > 0 && creditVerify.length() <= 3) &&
                resultCreditNum &&
                resultCreditYear &&
                resultCreditMonth &&
                resultPassword &&
                resultCreditVerify ){ //checks the form validity and length
            
            if( (Integer.parseInt( (String)creditYear ) > getYear() ) ){
                
                 //if tha expiration year is greater than current year then return true
                //since the expiration is in the future no need to check 
                //for the month
                return true;
            }
            else if( (Integer.parseInt( (String)creditYear ) == getYear() ) ){
                
                //if the expiration year is this year
                //then check the month
                if( (Integer.parseInt( (String)creditMonth ) >= getMonth()) ){
                    return true;
                }
                else{
                    return false;
                }
            }
            else{
                return false;
            }
        }
        else{
            return false;
        }
            
            
        /*if( creditMonth.length() > 0 && 
                creditYear.length() > 0 && 
                (creditNum.length() > 0 && creditNum.length() <= 16) &&
                (creditVerify.length() > 0 && creditVerify.length() <= 3) &&
                resultCreditNum &&
                resultCreditYear &&
                resultCreditMonth &&
                resultPassword ){
            if( (Integer.parseInt( (String)creditYear ) >= getYear() &&
                    Integer.parseInt( (String)creditMonth ) >= getMonth()) &&
                    (Integer.parseInt( (String)creditMonth ) > 0 && 
                    Integer.parseInt( (String)creditMonth ) <= 12) &&
                    !creditMonth.equals("") &&
                    !creditYear.equals("") &&
                    resultCreditVerify ){

                return true;

            }
            else{
                return false;
            }
        }
        else{
            LogManager.logEvent("Transaction." + Thread.currentThread().getStackTrace()[1].getMethodName(), Level.WARNING, "Transaction Unsuccessful - Invalid Input", request.getRemoteAddr(), String.valueOf(request.getSession().getAttribute("name")));
            return false;
        }*/
       
    }
    
    public static int getYear(){
        
        Calendar c = Calendar.getInstance();
        int y = c.get( Calendar.YEAR );
        
        return y;
    }
    
    private static int getMonth(){
        
        Calendar c = Calendar.getInstance();
        int m = c.get( Calendar.MONTH );
        
        return m;
    }
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        if( checkInput(request) ){
            processRequest(request, response);
        }
        else{
            response.sendRedirect("transaction.jsp?status=0");
        }
        
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        if( checkInput(request) ){
            processRequest(request, response);
        }
        else{
            response.sendRedirect("transaction.jsp?status=0");
        }
        
    }

    @Override
    public String getServletInfo() {
        return "Short description";
    }
    
}
